package ac.svn.accesscontrol.ui.helper;

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import ac.svn.accesscontrol.manager.LocationInformationManager;
import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.ui.StatusLabel;
import ac.svn.accesscontrol.ui.UIComponentLibrary;

public class UniqueLocationFinder implements FocusListener,KeyListener{

    public enum LOC_ATTRIBUTE
    {
	NAME,
	PATH
    };

    public enum MESSAGE_TYPE
    {
	INFORMATION,
	WARNING,
	ERROR, UNKNOWN
    }

    private JTextField 		targetTextField 	= null;
    private JComponent 		componentToDisable 	= null;
    private String 		existingValue 		= null;
    private LOC_ATTRIBUTE 	locAttribute 		= LOC_ATTRIBUTE.NAME;
    private StatusLabel		errorLabel		= null;
    private String 		lastError		= "";
    private boolean 		currentOpValid		= true;
    private Border		defBorder		= null;

    public UniqueLocationFinder(JTextField targetTextView)
    {
	this.targetTextField = targetTextView;
	errorLabel = (StatusLabel) UIComponentLibrary.getComponent(LocationInformationManager.ExportedComponents.C_ERROR_LABEL);
	if(null != this.targetTextField)
	{
	    defBorder = this.targetTextField.getBorder();
	}
    }

    @Override
    public void keyPressed(KeyEvent ke){}
    @Override
    public void keyTyped(KeyEvent ke){}
    @Override
    public void focusLost(FocusEvent fe){}

    @Override
    public void keyReleased(KeyEvent ke) 
    {	
	checkItemExistence();
    }

    @Override
    public void focusGained(FocusEvent fe) 
    {
	//checkItemExistence();
    }


    private void checkItemExistence()
    {
	if(null != targetTextField)
	{
	    String curText = targetTextField.getText().trim();

	    if(curText.isEmpty())
	    {
		String fieldName = "Name";

		if(LOC_ATTRIBUTE.PATH == locAttribute)
		{
		    fieldName = "Path";
		}
		targetTextField.setBorder(new LineBorder(Color.RED));
		targetTextField.setToolTipText(String.format("<html>The location %s is mandatory!", fieldName));
		showMessage(String.format("<html>A %s is mandatory for every location!", fieldName),MESSAGE_TYPE.ERROR);
		setComponentState(false);
		currentOpValid = false;
	    }
	    else
	    {
		//Check if are in editing mode or new creation.
		if(null != existingValue)
		{
		    //If we are editing locations. No need to perform check.
		    if(LOC_ATTRIBUTE.PATH == locAttribute)
		    {
			return;
		    }
		    else
		    {
			//If same location exist in svn information manager.
			if(true == SVNInfoManager.getInfoManager().isLocationWithNameExists(curText))
			{
			    //And existent name is the name already assigned to this location.
			    if(false == existingValue.equalsIgnoreCase(curText))
			    {
				targetTextField.setBorder(new LineBorder(Color.RED));
				targetTextField.setToolTipText(String.format("<html> A location with name<br>%s<br> already exists! Suggest another name!", curText));
				showMessage(String.format(String.format("<HTML> A location with name <b>\"%s\"</b> already exists! Suggest another name!", curText)),MESSAGE_TYPE.ERROR);
				lastError = "Name validattion[SUCCESS]";
				setComponentState(false);
				currentOpValid = false;
			    }
			    else
			    {
				targetTextField.setBorder(new LineBorder(Color.GREEN));
				targetTextField.setToolTipText(String.format(" Location can be given this name!", curText));
				lastError = "Name validattion[SUCCESS]";
				showMessage(" Location can be given this name!",MESSAGE_TYPE.INFORMATION);
				setComponentState(true);
				currentOpValid = true;
			    }
			}
			else
			{
			    targetTextField.setBorder(new LineBorder(Color.GREEN));
			    targetTextField.setToolTipText(String.format("Location can be given this name!", curText));
			    lastError = "";
			    showMessage(" Location can be given this name!",MESSAGE_TYPE.INFORMATION);
			    currentOpValid = true;
			}
		    }
		}
		else	//Section meant for new location addition.
		{
		    boolean exists = false;
		    String fieldName = "Name";

		    if(LOC_ATTRIBUTE.PATH == locAttribute)
		    {
			exists = SVNInfoManager.getInfoManager().isLocationWithPathExists(curText);
			fieldName = "Path";
		    }
		    else
		    {
			exists = SVNInfoManager.getInfoManager().isLocationWithNameExists(curText);
		    }

		    if(true == exists)
		    {
			targetTextField.setBorder(new LineBorder(Color.RED));
			targetTextField.setToolTipText(String.format("<html>A location with %s<br>%s<br> already exists! Suggest another %s!", fieldName,curText,fieldName));
			showMessage(String.format(String.format("<HTML>A location with %s <b>\"%s\"</b> already exists! Suggest another %s!", fieldName,curText,fieldName)),MESSAGE_TYPE.ERROR);
			lastError = String.format("A location with %s \"%s\" already exists! Suggest another name!", fieldName,curText);
			setComponentState(false);
			currentOpValid = false;
		    }
		    else
		    {
			targetTextField.setBorder(new LineBorder(Color.GREEN));
			targetTextField.setToolTipText(String.format("<html>Location can be created with mentioned %s.</HTML>",fieldName));
			lastError = String.format("%s validattion[SUCCESS]",fieldName);
			showMessage(String.format("<html>Location can be created with mentioned %s.</HTML>",fieldName),MESSAGE_TYPE.INFORMATION);
			setComponentState(true);
			currentOpValid = true;
		    }	
		}	 
	    }
	}
    }

    /***
     * Method is responsible for settings state of component which supposed to be disabled when field mentioned is not unique.
     * @param b
     */
    private void setComponentState(boolean b)
    {
	if(null != componentToDisable)
	{
	    componentToDisable.setEnabled(b);
	}
    }

    public LOC_ATTRIBUTE getLocAttribute() {
	return locAttribute;
    }

    public void setLocAttribute(LOC_ATTRIBUTE locAttribute) {
	this.locAttribute = locAttribute;
    }

    public void setComponentToDisable(JComponent componentToDisable) {
	this.componentToDisable = componentToDisable;
    }

    public JComponent getComponentToDisable() {
	return componentToDisable;
    }

    public String getExistingValue() {
	return existingValue;
    }

    public void setExistingValue(String existingValue) {
	this.currentOpValid = true;
	this.existingValue = existingValue;
    }

    private void showMessage(String messageString,MESSAGE_TYPE message_type)
    {
	if(null != errorLabel)
	{
	    errorLabel.setText(messageString);
	    switch (message_type) {
	    case INFORMATION:
		errorLabel.showInformationText(messageString);
		break;
	    case WARNING:
		errorLabel.showWarningText(messageString);
		break;
	    case ERROR:
		errorLabel.showErrorText(messageString);
		break;
	    case UNKNOWN:
		errorLabel.setText(messageString);
		break;
	    default:
		errorLabel.setText(messageString);
		break;
	    }	    
	}
    }

    public String getLastError() {
	return lastError;
    }

    public void setLastError(String lastError) {
	this.lastError = lastError;
    }

    public boolean isCurrentOpValid() {
	checkItemExistence();
        return currentOpValid;
    }

    public void setCurrentOpValid(boolean currentOpValid) {
        this.currentOpValid = currentOpValid;
    }

    public void resetBorder()
    {
	this.targetTextField.setBorder(defBorder);
    }
}
